# package deb

# import (
# 	"os"
# 	"path/filepath"
# 	"sort"
# 	"strings"

# 	"github.com/aptly-dev/aptly/aptly"
# 	"github.com/aptly-dev/aptly/pgp"
# 	"github.com/aptly-dev/aptly/utils"
# )
from typing import List,Dict
from .package_files import *
from .listp import *
from .package_collection import *
from .formatp import *
from .package import *
from .deb import *
import utils
from .version import *
import os
# // CollectPackageFiles walks filesystem collecting all candidates for package files
def CollectPackageFiles(locations :List[str], reporter ) :
    failedFiles=[]
    packageFiles=[]
    otherFiles=[]
    for  location in locations :

        try:
            os.stat(location)
        except:
            print("Error:Unable to process {}: ".format( location))
            failedFiles.append( location)
            continue
            
        if os.path.isdir(location) :
            try:
                for root, dirs, files in os.walk(location, topdown=False):
                    for name in files:
                        fileName=os.path.join(root, name)
                        if fileName.endswith( ".deb") or fileName.endswith( ".udeb") or fileName.endswith( ".dsc") or fileName.endswith(".ddeb") :
                            packageFiles . append( fileName)
                        elif fileName.endwith( ".buildinfo") :
                            otherFiles.append( fileName)
            except:
                print("Waring:Unable to process {}".format( location))
                failedFiles . append(location)
                continue
                

        else :
            if location.endswith( ".deb") or location.endswith( ".udeb") or location.endswith( ".dsc") or location.endswith( ".ddeb") :
                packageFiles. append( location)
            elif location.endswith( ".buildinfo") :
                otherFiles. append( location)
            else :
                print("Unknown file extension: {}".format( location))
                failedFiles. append( location)
                continue


    packageFiles.sort()
    return    (packageFiles,    otherFiles,failedFiles)


# // ImportPackageFiles imports files into local repository
def ImportPackageFiles(packageList :PackageList, packageFiles :List[str], forceReplace :bool, verifier ,
    pool , collection :PackageCollection, reporter , restriction ,
    checksumStorageProvider ):
    failedFiles=[]
    candidateProcessedFiles=[]
    processedFiles=[]
    if forceReplace :
        packageList.PrepareIndex()
    

    transaction= collection.db
    # defer transaction.Discard()

    checksumStorage = checksumStorageProvider(transaction)

    for file in packageFiles :
        
        stanza=None
        p  =None
        

        candidateProcessedFiles = []
        isSourcePackage = file.endswith( ".dsc")
        isUdebPackage = file.endswith( ".udeb")
        if isSourcePackage :
            stanza= GetControlFileFromDsc(file, verifier)

            # if err is None  :
            stanza.data["Package"] = stanza.data["Source"]
            stanza.data.delete( "Source")

            p= NewSourcePackageFromControlFile(stanza)
            
        else :
            stanza,err = GetControlFileFromDeb(file)
            if isUdebPackage :
                p = NewUdebPackageFromControlFile(stanza)
            else :
                p = NewPackageFromControlFile(stanza)
        # except:
        
        
        #     print("Error:Unable to read file {}: ".format( file))
        #     failedFiles.append( file)
        #     continue
        

        if p.Name == "" :
            print("Empty package name on ", file)
            failedFiles.append( file)
            continue
        

        if p.Version == "" :
            print("Empty version on ", file)
            failedFiles.append( file)
            continue
        

        if p.Architecture == "" :
            print("Empty architecture on ", file)
            failedFiles.append( file)
            continue
        

        files =PackageFiles() #PackageFiles

        if isSourcePackage :
            files = p.Files()
        
        # var checksums utils.ChecksumInfo
        checksums = utils.checksum.ChecksumsForFile(file)
       
        mainPackageFile = PackageFile()
        mainPackageFile.Filename= os.path.basename(file)
        print('{}_{}_{}.{}'.format(p.Name,p.Version,p.Architecture,os.path.basename(file).split('.')[-1]))
        mainPackageFile.Filename='{}_{}_{}.{}'.format(p.Name,p.Version,p.Architecture,os.path.basename(file).split('.')[-1])
        mainPackageFile.Checksums= checksums
        
        try:
            mainPackageFile.PoolPath = pool.Import(file, mainPackageFile.Filename, mainPackageFile.Checksums, False, checksumStorage)
        except:
            print("Unable to import file {} into pool: ".format( file))
            failedFiles.append( file)
            continue
        

        candidateProcessedFiles.append( file)

        # // go over all the other files
        for i in files :
            sourceFile = os.path.join(os.path.dirname(file), os.path.basename(files[i].Filename))
            try:
                os.Stat(sourceFile)
            except:
                # // if file is not present, try to find it in the pool
                
                
                found :bool=None
                raise

                # files[i].PoolPath, found, err2 = pool.Verify("", files[i].Filename, &files[i].Checksums, checksumStorage)
                # if err2 is not None  {
                #     err = err2
                # } else if found {
                #     // clear error, file is already in the package pool
                #     err = None
                # }
            
            files[i].PoolPath = pool.Import(sourceFile, files[i].Filename, files[i].Checksums, False, checksumStorage)
            
            candidateProcessedFiles .append( sourceFile)
            
             
            


                # print("Unable to import file %s into pool: %s", sourceFile, err)
                # failedFiles = append(failedFiles, file)
                # break
            
        
        # if err is not None  {
        #     # // some files haven't been imported
        #     continue
        files.append( mainPackageFile)
        
        p.UpdateFiles(files)

        if restriction is not None  :
            if not restriction.Matches(p) :
                print("%s has been ignored as it doesn't match restriction", p)
                failedFiles.append( file)
                continue
        

        err = collection.UpdateInTransaction(p)
        if err is not None  :
            print("Unable to save package %s: %s", p, err)
            failedFiles.append( file)
            continue
        

        if forceReplace :
            dependency=Dependency()
            dependency.Pkg= p.Name,
            dependency.Version=p.Version
            dependency.Relation=VersionRelation. VersionEqual 
            dependency.Architecture= p.Architecture
            conflictingPackages = packageList.Search(dependency, True)
            for  cp in conflictingPackages :
                print("Remove:%s removed due to conflict with package being added", cp)
                packageList.Remove(cp)

        err = packageList.Add(p)
        if err is not None  :
            print("Unable to add package to repo %s: %s", p, err)
            failedFiles . append( file)
            continue
        

        print("%s added", p)
        # processedFiles . append( candidateProcessedFiles...)
        processedFiles=processedFiles+candidateProcessedFiles
    

    # err = transaction.Commit()
    return (processedFiles,failedFiles)